//
// Created by zhupi on 2024/11/5.
//

#ifndef DEMO2_TEST_TABLE_WIDGET_H
#define DEMO2_TEST_TABLE_WIDGET_H

#include <QTableWidget>
#include <QHeaderView>
#include <QComboBox>
#include <QItemDelegate>
#include <QTableWidgetItem>
#include <QComboBox>
#include <QLineEdit>
#include <QPushButton>


class ComboBoxDelegate : public QItemDelegate {
Q_OBJECT

public:

signals:
    void editorTypeChanged(const QString &text, const QModelIndex &index) const;

public:
    ComboBoxDelegate(QObject *parent = nullptr) : QItemDelegate(parent) {}

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const override {
        auto *comboBox = new QComboBox(parent);
        // 假设下拉框有三个选项
        comboBox->addItems({"Option 1", "Option 2", "Option 3"});
        comboBox->setProperty("row", index.row());
        comboBox->setProperty("col", index.column());

        connect(comboBox, &QComboBox::currentTextChanged, this, [=](const QString &text) {
            int row = comboBox->property("row").toInt();
            int col = comboBox->property("col").toInt();
            QAbstractItemModel *model = const_cast<QAbstractItemModel*>(index.model());
            model->setData(model->index(row, col), text);
            emit editorTypeChanged(text, index);
        });

        return comboBox;
    }

    void setEditorData(QWidget *editor, const QModelIndex &index) const override {
        auto *comboBox = static_cast<QComboBox *>(editor);
        comboBox->setCurrentText(index.data().toString());
    }

    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override {
        auto *comboBox = static_cast<QComboBox *>(editor);
        model->setData(index, comboBox->currentText());
    }


};


class TableWidget : public QTableWidget {
Q_OBJECT

public:
    TableWidget(QWidget *parent = nullptr) : QTableWidget(parent) {
        this->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

        connect(this, &QTableWidget::cellChanged, this, &TableWidget::updateLocalCache);
        connect(horizontalHeader(), &QHeaderView::sectionClicked, this, &TableWidget::toggleSortOrder);
        auto *comboDelegate = new ComboBoxDelegate(this);
        connect(comboDelegate, &ComboBoxDelegate::editorTypeChanged, this, &TableWidget::onEditorTypeChanged);
        setItemDelegateForColumn(1, comboDelegate);  // 假设第2列需要下拉框
    }

    void onEditorTypeChanged(const QString &text, const QModelIndex &index) {
        if (index.column() == 1) { // 第二列
            if (text == "Option 1") {
                setCellWidget(index.row(), index.column() + 1, new QLineEdit(this));
            } else if (text == "Option 2") {
                auto *comboBox = new QComboBox(this);
                comboBox->addItems({"1", "2", "3"});
                setCellWidget(index.row(), index.column() + 1, comboBox);
            } else if (text == "Option 3") {
                auto *button = new QPushButton("Click Me", this);
                connect(button, &QPushButton::clicked, this, [this, index]() {
                    emit buttonClicked(index);
                });
                setCellWidget(index.row(), index.column() + 1, button);
            }
        }
    }

    // 加载表格数据的接口
    void loadTableData(const std::vector<std::vector<QString>> &data) {
        dataVec = data;
        setRowCount(static_cast<int>(data.size()));
        if (!data.empty()) {
            setColumnCount(static_cast<int>(data[0].size()));
        }

        // 填充表格
        for (int row = 0; row < rowCount(); ++row) {
            for (int col = 0; col < columnCount(); ++col) {
                auto *item = new QTableWidgetItem(data[row][col]);
                setItem(row, col, item);
            }
        }

        // 设置代理
//        for (int col = 0; col < columnCount(); ++col) {
//            if (needsComboBox(col)) {  // 假设 col 列需要下拉框
//                setItemDelegateForColumn(col, new ComboBoxDelegate(this));
////                setItem
//            }
//        }

        originalData = dataVec;
        naturalSortOrder = true;
    }

    // 在指定行下面添加一行数据
    void AddRow(int row, const std::vector<QString> &data) {
        if (data.size() != static_cast<size_t>(columnCount())) return;

        // 插入一行
        insertRow(row + 1);
        for (int col = 0; col < columnCount(); ++col) {
            auto *item = new QTableWidgetItem(data[col]);
            setItem(row + 1, col, item);
        }

        // 更新缓存数据
        dataVec.insert(dataVec.begin() + row + 1, data);
    }

    // 修改指定行的数据，并同步到缓存数据
    void ChangeLineData(int row, const std::vector<QString> &data) {
        if (row < 0 || row >= rowCount() || data.size() != static_cast<size_t>(columnCount())) return;

        for (int col = 0; col < columnCount(); ++col) {
            item(row, col)->setText(data[col]);
        }

        // 同步缓存数据
        dataVec[row] = data;
    }
signals:
    void buttonClicked(const QModelIndex &index);

private slots:
    // 切换排序
    void toggleSortOrder(int column) {
        if (naturalSortOrder) {
            sortByColumn(column, Qt::AscendingOrder);
        } else {
            clearContents();
            loadTableData(originalData);
        }
        naturalSortOrder = !naturalSortOrder;

        // 排序后同步缓存数据
        syncCacheWithCurrentOrder();
    }

    // 更新本地缓存
    void updateLocalCache(int row, int col) {
        dataVec[row][col] = item(row, col)->text();
    }

public:
    // 同步缓存与当前显示顺序
    void syncCacheWithCurrentOrder() {
        for (int row = 0; row < rowCount(); ++row) {
            for (int col = 0; col < columnCount(); ++col) {
                dataVec[row][col] = item(row, col)->text();
            }
        }
    }

    // 判断列是否需要下拉框代理
    bool needsComboBox(int col) {
        // 假设第1列需要下拉框
        return col == 1;
    }

    std::vector<std::vector<QString>> dataVec;
    std::vector<std::vector<QString>> originalData;
    bool naturalSortOrder;

};


#endif //DEMO2_TEST_TABLE_WIDGET_H
